package com.bsh.serviceImpl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.bsh.mybatis.model.Account;
import com.bsh.mybatis.model.AccountNotice;
import com.bsh.mybatis.model.CloudReferrals;
import com.bsh.mybatis.model.Merchant;
import com.bsh.mybatis.model.User;
import com.bsh.repository.DaoAccount;
import com.bsh.repository.DaoAccountLog;
import com.bsh.repository.DaoAccountNotice;
import com.bsh.repository.DaoCloudReferrals;
import com.bsh.repository.DaoMerchant;
import com.bsh.repository.DaoPartner;
import com.bsh.repository.DaoUser;
import com.bsh.service.RecommendService;
import com.bsh.utils.PrimaryGenerater;

/**
 * 推荐返币 ,升级返现 合伙人返币
 * 
 * @author jane
 *
 */
@Service
@Transactional
public class RecommendServiceImpl implements RecommendService {

	private static Logger log = LoggerFactory
			.getLogger(RecommendServiceImpl.class);
	// private Integer userId;
	// private Integer toUserId;
	// private BigDecimal total; //金额 现金
	// private BigDecimal totalCloud; //商币
	// private Integer pid; //推荐人 id (id是表的自增的唯一id)
	// private Integer pName; //推荐人 user_name (账户名称)
	// private String type; //情景类型 如: 在线支付转账( transferByOnline
	// ),transferByCash...
	//
	@Autowired
	private DaoAccount daoAcc;
	@Autowired
	private DaoUser daoUser;
	@Autowired
	private DaoMerchant daoMer;
	@Autowired
	private DaoPartner daoPar;
	@Autowired
	DaoAccountNotice daoNotice;
	@Autowired
	DaoAccountLog daoAccLog;
	@Autowired
	DaoCloudReferrals daoCloudRef;

	/*新规则 收取上级收入的50% 无限*/
	BigDecimal everMemberUpgradeFee = new BigDecimal("0.3");    //会员升级的提成比例
	BigDecimal everMemberFee = new BigDecimal("0.5");    //会员升级得上家的50%

	BigDecimal everTransferFee = new BigDecimal("0.5");    //商家收款得上家的50%
	BigDecimal everTransferMerchantFee = new BigDecimal("0.04");    //商家收款 收款行为上家暂定为 4%
	BigDecimal everTransferSaleFee = new BigDecimal("0.06");    //消费行为上家 暂定为6%
	
	/*合伙人返商币 比例*/
	BigDecimal areaPartnerFee = new BigDecimal("0.04");      //区合伙人原来比例为 0.02
	BigDecimal cityPartnerFee = new BigDecimal("0.03");     //市合伙人原来比例为 0.015
	BigDecimal provincePartnerFee = new BigDecimal("0.02");  //省合伙人原来比例为 0.01
	BigDecimal countryPartnerFee = new BigDecimal("0.01");  //全国合伙人原来比例为 0.005
	//20160827改为原来的2倍,  区原0.02改为0.04
	
	/**
	 * 余额转账 ,用余额转给会员或商家
	 * 
	 * @param userId    转出者
	 * @param toUserId  接收者
	 * @param total     总金额
	 * @param sn        流水号
	 * @param referrerType       trade_type 交易类型(推荐人返币 标记)
	 * @param partnerType        就是trade_type 交易类型(用于合伙人返币 标记)
	 * @return
	 */
	protected Integer transferCommissionAction(Integer userId, Integer toUserId, BigDecimal total, String sn, Integer referrerType,
			Integer partnerType) {
		Integer res = -1;
		User userInfo = daoUser.getUser(userId);
		User toUserInfo = daoUser.getUser(toUserId);
		Account toAccInfo = daoAcc.getUserAccount(toUserId);
		if (toAccInfo == null) {
			daoAcc.initUserAcount(toUserId);
		}
		if(toUserInfo.getIsMerchant() ==null || toUserInfo.getIsMerchant() != 1){
			log.error("transferCommissionAction::只有商家才能收款"+toUserId+" Total:"+total+ " SN:["+sn+"]");
			return -9;	 //只有商家收款的 消费行为才进行推荐奖励
		}
		
		// 检查转账人是否有推荐人 [转账人是 支出] * 3% 是支出消费都是 3%
		if (userInfo.getPid() != null && userInfo.getPid() != 0) {
			String type = "C";  //消费行为对 C端

			//二级分销 20160809 郑总改游戏规则
			//重构 使用统一入口
			res = transferCommission(total, type, userInfo.getId(),userInfo.getId(), sn, referrerType);
			
		}

		// 被转账人是 [ 收入 ] 检查被转账人是否有推荐人
		if (toUserInfo.getPid() != null && toUserInfo.getPid() != 0) {
			String type = "B";  // 商家收款行为对 B端
			//二级分销 20160809 郑总改游戏规则
			//重构 使用统一入口
			res = transferCommission(total, type, toUserInfo.getId(),userInfo.getId(), sn, referrerType);
		}
		
		//合伙人推荐奖励统一入口， 含商币和 现金  20160818
		commissionPartner(toUserId, userId, total, sn, partnerType,"transferCommissionAction");
		// int s = 1 / 0;

		return res;
	}

	/**
	 * 推荐人返云币
	 * 
	 * @param totalCloudmoney		总金额！
	 * @param fee
	 * @param pId			主要!	要加币或现金的用户id ，主要以这个id进行相关操作
	 * @param userId			推荐奖励的交易来源发起者用户id，只用来记录 FromUser 别无用处
	 * @param sn
	 * @param type trade_type 交易类型
	 * @return
	 */
	protected Integer referrerCloudMoney(BigDecimal totalCloudmoney, BigDecimal fee, Integer pId, Integer userId,String sn, Integer type) {
		Integer res = -1;
		if (pId == null || userId == null || fee.compareTo(new BigDecimal("0")) == 0
				|| totalCloudmoney.compareTo(new BigDecimal("0")) == 0
				|| totalCloudmoney.compareTo(new BigDecimal("0")) == -1) {
			return -1;
		}
		String ip = "";
		// 推荐奖商币 (money*fee)
		BigDecimal intoCloudMoney = totalCloudmoney.multiply(fee);
		intoCloudMoney = intoCloudMoney.setScale(2, BigDecimal.ROUND_DOWN);
		// System.out.println(intoCloudMoney + " ===" + total + "||" + fee );
		if (intoCloudMoney.compareTo(new BigDecimal("0.00")) == -1
				|| intoCloudMoney.compareTo(new BigDecimal("0.00")) == 0) {
			return -1;
		}

		Account accInfo = daoAcc.getUserAccount(pId);
		Integer accountId;
		if (accInfo == null) {
			accountId = daoAcc.initUserAcount(pId);
		} else {
			accountId = accInfo.getId();
		}
		daoAccLog.addLog(accountId, sn, ip);
		// 账户变动前记录日志

		res = daoAcc.addCloudMoney(accountId, pId, intoCloudMoney);
		AccountNotice noticeCloud = new AccountNotice();
		noticeCloud.setAccountId(accountId);
		noticeCloud.setUserid(pId);
		noticeCloud.setCloudMoney(intoCloudMoney);// 商币

		noticeCloud.setTradeType((int) type); // trade_type 交易类型 \10余额转账给推荐人返币

		String snTemp = PrimaryGenerater.getInstance().next();
		noticeCloud.setCsn(sn);// 这笔转账动作流水号
		noticeCloud.setSn(snTemp);// 唯一流水号
		noticeCloud.setOuterTime(new Date());
		noticeCloud.setOperator(-1); // -1系统操作

		noticeCloud.setTitle(String.format("由被推荐人交易得到商币+%s", intoCloudMoney));
		noticeCloud.setPaymentId(3);// 系统操作
		noticeCloud.setIp(ip);
		noticeCloud.setIsPaid((byte) 1);// 已付款
		noticeCloud.setMoneyType((short) 0);// 商币类型0,
		noticeCloud.setCreateTime(new Date());
		noticeCloud.setFromUserId(userId); // 推荐奖来自哪个用户
		// 在查
		Account downAccInfoCloud = daoAcc.selectByPrimaryKey(accountId);
		noticeCloud.setMoneyDown(downAccInfoCloud.getMoney()); // 结存现金余额
		noticeCloud.setCloudMoneyDown(downAccInfoCloud.getCloudMoney()); // 结存商币余额
		res = daoNotice.insert(noticeCloud);

		// 同时在记录到 cloud_referrals
		BigDecimal money = new BigDecimal("0");
		cloudReferrals(pId, userId, sn, type, intoCloudMoney, money);

		return res;
	}
	
	/**
	 * 推荐人返现金- 新游戏规则 20160818
	 * 现金奖励
	 * 
	 * @param bshCashMoney		!注意基数值! 不是总额，而是15%那部分
	 * @param fee				   奖励比例 例如 0.15 
	 * @param doUserId			!重要，以这个id进行相关资金操作
	 * @param fromUserId		  来源
	 * @param sn
	 * @param tradeType trade_type 交易类型
	 * @return
	 */
	protected Integer referrerMoney(BigDecimal bshCashMoney, BigDecimal fee, Integer doUserId, Integer fromUserId,String sn, Integer tradeType) {
		Integer res = -1;
		if(bshCashMoney == null || fee == null || tradeType == null || sn == null){
			log.error("referrerMoney::NULL sn "+sn);
			return -2;
		}
		if (doUserId == null || fromUserId == null || fee.compareTo(new BigDecimal("0")) == 0
				|| bshCashMoney.compareTo(new BigDecimal("0")) <=0 ) {
			return -3;
		}
		String ip = "";
		// 推荐现金 (money*fee)
		BigDecimal intoMoney = bshCashMoney.multiply(fee);
		intoMoney = intoMoney.setScale(2, BigDecimal.ROUND_DOWN);
		// System.out.println(intoCloudMoney + " ===" + total + "||" + fee );
		if (intoMoney.compareTo(new BigDecimal("0.00")) <=0) {
			return -4;
		}

		Account accInfo = daoAcc.getUserAccount(doUserId);
		Integer accountId;
		if (accInfo == null) {
			accountId = daoAcc.initUserAcount(doUserId);
		} else {
			accountId = accInfo.getId();
		}
		daoAccLog.addLog(accountId, sn, ip);
		// 帐户变动前记录日志

		res = daoAcc.addMoney(accountId, doUserId, intoMoney);
		AccountNotice noticeMoney = new AccountNotice();
		noticeMoney.setAccountId(accountId);
		noticeMoney.setUserid(doUserId);
		noticeMoney.setMoney(intoMoney);// 现金

		noticeMoney.setTradeType((int) tradeType); // trade_type 交易类型 \10余额转账给推荐人返币

		String snTemp = PrimaryGenerater.getInstance().next();
		noticeMoney.setCsn(sn);// 这笔转账动作流水号
		noticeMoney.setSn(snTemp);// 唯一流水号
		noticeMoney.setOuterTime(new Date());
		noticeMoney.setOperator(-1); // -1系统操作

		noticeMoney.setTitle(String.format("由被推荐人交易增加+%s", intoMoney));
		noticeMoney.setPaymentId(3);// 系统操作
		noticeMoney.setIp(ip);
		noticeMoney.setIsPaid((byte) 1);// 已付款
		noticeMoney.setMoneyType((short) 1);// 现金类型1,
		noticeMoney.setCreateTime(new Date());
		noticeMoney.setFromUserId(fromUserId); // 推荐奖来自哪个用户
		// 在查
		Account downAccInfo = daoAcc.selectByPrimaryKey(accountId);
		noticeMoney.setMoneyDown(downAccInfo.getMoney()); // 结存现金余额
		noticeMoney.setCloudMoneyDown(downAccInfo.getCloudMoney()); // 结存积分余额
		res = daoNotice.insert(noticeMoney);

		// 同时在记录到 cloud_referrals
		BigDecimal cloudMoney = new BigDecimal("0");
		cloudReferrals(doUserId, fromUserId, sn, tradeType, cloudMoney , intoMoney);

		return res;
	}

	/**
	 * 给合伙人返币
	 * 加新规则 奖励现金 20160818
	 * 
	 * @param merchantId		!主要根据
	 * @param userId			暂不使用，保留
	 * @param toUserId			暂不使用，保留
	 * @param total				金额
	 * @param sn				流水号
	 * @param partnerType		交易类型- trade_type
	 * @param type				场景，使用合伙人奖励的具体场景如 transferCommissionAction , adminAddCloudMoneyPartner ,buyCloudMoney
	 * @return
	 */
	protected Integer recommendPartner(Integer merchantId, Integer userId, Integer toUserId, BigDecimal total, String sn,
			Integer partnerType, String type) {
		Integer res = -1;
		Merchant merchant = daoMer.selectByPrimaryKey(merchantId);
		if (merchant.getProvince() == null && merchant.getCity() == null && merchant.getArea() == null) {
			return -1;
		}
		Integer province = merchant.getProvince();
		Integer city = merchant.getCity();
		Integer area = merchant.getArea();

		// 区县 0.02
		List<Map<String, Object>> areaPartnerList = daoPar.getAreaPartner(province, city, area);
		doPartner(areaPartnerList, this.areaPartnerFee, total, sn, partnerType);
		
		// 市级 0.015
		List<Map<String, Object>> cityPartnerList = daoPar.getCityPartner(province, city);
		doPartner(cityPartnerList, this.cityPartnerFee, total, sn, partnerType);

		// 省 0.01
		List<Map<String, Object>> provincePartnerList = daoPar.getProvincePartner(province);
		doPartner(provincePartnerList, this.provincePartnerFee, total, sn, partnerType);

		// 全国0.005
		List<Map<String, Object>> countryPartnerList = daoPar.getCountryPartner();
		doPartner(countryPartnerList, this.countryPartnerFee, total, sn, partnerType);

		//新规则 begin 20160818
			//现金奖励比例 新规则 20160818
			BigDecimal areaPartnerCashFee = new BigDecimal("0.02"); //区县 2%的 现金奖励
			BigDecimal cityPartnerCashFee = new BigDecimal("0.015"); //市级      1.5%的 现金奖励 
			BigDecimal provincePartnerCashFee = new BigDecimal("0.01"); //省级   1%的 现金奖励 
			BigDecimal countryPartnerCashFee = new BigDecimal("0.005"); //全国级  0.5%的 现金奖励 
			
			//transferCommissionAction , adminAddCloudMoneyPartner ,buyCloudMoney
			//!!! 目前没有开后台加商币的 合伙人返现金！
			if( type.equals("transferCommissionAction") || type.equals("buyCloudMoney") ){
				//【这个金额得是平台收的15%】 bshMoney
				BigDecimal bshMoney = total.multiply(new BigDecimal("0.15"));

				//20160826 郑总改规则, 去掉返现金规则 合伙人返现金 . 
				//20160826b 先不去掉等做好全部在一起上
				//20160827做好新规则一起上， 无限级50%,同时去掉返现金
//				doCashPartner(areaPartnerList, areaPartnerCashFee, bshMoney, sn, partnerType);
//				doCashPartner(cityPartnerList, cityPartnerCashFee, bshMoney, sn, partnerType);
//				doCashPartner(provincePartnerList, provincePartnerCashFee, bshMoney, sn, partnerType);
//				doCashPartner(countryPartnerList, countryPartnerCashFee, bshMoney, sn, partnerType);
				
			}
		//END 20160818
		
		return res;
	}

	/**
	 * 实际操作合伙人list 并for遍历加币
	 * 
	 * @param partnerList
	 * @param fee
	 * @param total
	 * @param sn
	 * @param partnerType  就是trade_type
	 * @return
	 */
	protected Integer doPartner(List<Map<String, Object>> partnerList, BigDecimal fee, BigDecimal total, String sn,Integer partnerType) {
		Integer res = -1;
		String ip = "";
		int numPartners = partnerList.size();
		if (numPartners <= 0) {
			return -1;
		}
		if(fee.compareTo(new BigDecimal("0.00")) <=0 ){
			return -2;
		}
		if(total.compareTo(new BigDecimal("0.00")) <=0 ){
			return -3;
		}
		for (int i = 0; i < partnerList.size(); i++) {
			Map<String, Object> nM = partnerList.get(i);

			// 合伙人得到的是 (money*fee)/该区的合伙人总数 ，平分
			BigDecimal singleMoney = total.multiply(fee).divide(new BigDecimal(Integer.toString(numPartners) ) , 2 , BigDecimal.ROUND_HALF_UP);
			if (singleMoney.compareTo(new BigDecimal("0.00")) == -1
					|| singleMoney.compareTo(new BigDecimal("0.00")) == 0)
				continue;
			singleMoney = singleMoney.setScale(2, BigDecimal.ROUND_DOWN);
			// System.out.println(singleMoney + " ===" + total + "||" + fee + "
			// >>" + numPartners);
		
			Integer userid = (Integer) nM.get("userid");
			Account accInfo = daoAcc.getUserAccount(userid);
			Integer accountId;
			if (accInfo == null) {
				accountId = daoAcc.initUserAcount(userid);
			} else {
				accountId = accInfo.getId();
			}
			daoAccLog.addLog(accountId, sn, ip);
			// 账户变动前记录日志

			res = daoAcc.addCloudMoney(accountId, userid, singleMoney);
			AccountNotice noticeCloud = new AccountNotice();
			noticeCloud.setAccountId(accountId);
			noticeCloud.setUserid(userid);
			noticeCloud.setCloudMoney(singleMoney);// 商币

			noticeCloud.setTradeType((int) partnerType); // 11余额转账给合伙人返币
															// ,13在线支付转账给合伙人返币
			noticeCloud.setSn(sn);// 流水号
			String snTemp = PrimaryGenerater.getInstance().next();
			noticeCloud.setCsn(sn);// 这笔转账动作流水号
			noticeCloud.setSn(snTemp);// 唯一流水号
			noticeCloud.setOuterTime(new Date());
			noticeCloud.setOperator(-1); // -1系统操作

			noticeCloud.setTitle(String.format("资金交易,合伙人增加商币+%s ", singleMoney));
			noticeCloud.setPaymentId(3);// 系统操作
			noticeCloud.setIp(ip);
			noticeCloud.setIsPaid((byte) 1);// 已付款
			noticeCloud.setMoneyType((short) 0);// 商币类型0,
			noticeCloud.setCreateTime(new Date());
			// 在查
			Account downAccInfoCloud = daoAcc.selectByPrimaryKey(accountId);
			// noticeCloud.setMoneyDown( accInfo.getMoney().subtract(money) );
			// //结存现金余额
			noticeCloud.setMoneyDown(downAccInfoCloud.getMoney()); // 结存现金余额
			noticeCloud.setCloudMoneyDown(downAccInfoCloud.getCloudMoney()); // 结存商币余额
			res = daoNotice.insert(noticeCloud);

		}
		return res;
	}
	
	/**
	 * 实际操作合伙人list 并for遍历 奖励 现金
	 * 现金奖励合伙人 新规则 20160818
	 * 
	 * @param partnerList   合伙人列表
	 * @param fee			比例
	 * @param bshMoney	    !!平台收取的15%现金!! ，不是总额！ 注意基数
	 * @param sn			流水号
	 * @param partnerType    就是trade_type交易类型
	 * @return
	 */
	protected Integer doCashPartner(List<Map<String, Object>> partnerList, BigDecimal fee, BigDecimal bshMoney, String sn,Integer partnerType) {
		Integer res = -1;
		String ip = "";
		int numPartners = partnerList.size();
		if (numPartners <= 0) {
			return -1;
		}
		if(fee.compareTo(new BigDecimal("0.00")) <=0 ){
			return -2;
		}
		if(bshMoney.compareTo(new BigDecimal("0.00")) <=0 ){
			return -3;
		}
		for (int i = 0; i < partnerList.size(); i++) {
			Map<String, Object> nM = partnerList.get(i);

			// 合伙人得到的是 (money*fee)/该区的合伙人总数 ，平分
			BigDecimal singleMoney = bshMoney.multiply(fee).divide(new BigDecimal(Integer.toString(numPartners) ) , 2 , BigDecimal.ROUND_HALF_UP);
			if (singleMoney.compareTo(new BigDecimal("0.00")) <=0)
				continue;
			singleMoney = singleMoney.setScale(2, BigDecimal.ROUND_DOWN);
			// System.out.println(singleMoney + " ===" + total + "||" + fee + "
			// >>" + numPartners);
		
			Integer userid = (Integer) nM.get("userid");
			Account accInfo = daoAcc.getUserAccount(userid);
			Integer accountId;
			if (accInfo == null) {
				accountId = daoAcc.initUserAcount(userid);
			} else {
				accountId = accInfo.getId();
			}
			daoAccLog.addLog(accountId, sn, ip);
			// 账户变动前记录日志

			log.info("给合伙人返现金addMoney:"+singleMoney+" uid:["+userid+"] sn:["+sn+"]");
			res = daoAcc.addMoney(accountId, userid, singleMoney);
			AccountNotice noticeMoney = new AccountNotice();
			noticeMoney.setAccountId(accountId);
			noticeMoney.setUserid(userid);
			noticeMoney.setMoney(singleMoney);// 现金！！

			noticeMoney.setTradeType((int) partnerType); // 11余额转账给合伙人返币
															// ,13在线支付转账给合伙人返币
			noticeMoney.setSn(sn);// 流水号
			String snTemp = PrimaryGenerater.getInstance().next();
			noticeMoney.setCsn(sn);// 这笔转账动作流水号
			noticeMoney.setSn(snTemp);// 唯一流水号
			noticeMoney.setOuterTime(new Date());
			noticeMoney.setOperator(-1); // -1系统操作

			noticeMoney.setTitle(String.format("资金交易,合伙人得到+%s ", singleMoney));
			noticeMoney.setPaymentId(3);// 系统操作
			noticeMoney.setIp(ip);
			noticeMoney.setIsPaid((byte) 1);// 已付款
			noticeMoney.setMoneyType((short) 1);// 现金类型1,
			noticeMoney.setCreateTime(new Date());
			// 在查
			Account downAccInfoMoney = daoAcc.selectByPrimaryKey(accountId);
			// noticeCloud.setMoneyDown( accInfo.getMoney().subtract(money) );
			// //结存现金余额
			noticeMoney.setMoneyDown(downAccInfoMoney.getMoney()); // 结存现金余额
			noticeMoney.setCloudMoneyDown(downAccInfoMoney.getCloudMoney()); // 结存商币余额
			res = daoNotice.insert(noticeMoney);

		}
		return res;
	}

	protected Integer cloudReferrals(Integer pId, Integer userId, String sn, Integer type, BigDecimal cloudMoney,
			BigDecimal money) {
		Integer res = -1;
		// user_id,user_name , rel_user_id, rel_user_name,money,cloud_money,
		// pay_time,type , create_time,sn
		User userInfo = daoUser.selectByPrimaryKey(userId);
		User pUserInfo = daoUser.selectByPrimaryKey(pId);
		if (userInfo == null || pUserInfo == null) {
			return -1;
		}
		CloudReferrals record = new CloudReferrals();
		record.setUserId(pId);
		record.setUserName(pUserInfo.getName());
		record.setRelUserId(userId);
		record.setRelUserName(userInfo.getName());
		if (cloudMoney.compareTo(new BigDecimal("0")) == 1) {
			record.setCloudMoney(cloudMoney);
			record.setType((byte) 1);
		}
		if (money.compareTo(new BigDecimal("0")) == 1) {
			record.setMoney(money);
			record.setType((byte) 2);
		}
		record.setPayTime(new Date());
		record.setCreateTime(new Date());
		record.setSn(sn);
		res = daoCloudRef.insertSelective(record);

		return res;
	}

	/**
	 * 用余额转
	 */
	@Override
	public Integer transferByCash(Integer userId, Integer toUserId, BigDecimal total, String sn) {
		Integer referrerType = 10; // trade_type 交易类型 \10余额转账给推荐人返币\11余额转账给合伙人返币
		Integer partnerType = 11;	//就是trade_type用于合伙人返币上
		return transferCommissionAction(userId, toUserId, total, sn, referrerType, partnerType);
	}

	/**
	 * 支线支付转
	 */
	@Override
	public Integer transferByOnline(Integer userId, Integer toUserId, BigDecimal total, String sn) {
		Integer referrerType = 12; // trade_type 交易类型
									// \12在线支付转账给推荐人返币\13在线支付转账给合伙人返币
		Integer partnerType = 13;  //就是trade_type用于合伙人返币上
		return transferCommissionAction(userId, toUserId, total, sn, referrerType, partnerType);
	}

	protected Integer memberUpgrade(String level,Integer userId, BigDecimal money,BigDecimal fee,String sn, Integer type){
		Integer res = -1;
		User userInfo = daoUser.getUser(userId);
		if( userInfo == null){
			return -1;
		}
		if( level == null){
			return -1;
		}
		if( !userInfo.getLevel().equals(level) ){
			return -1;
		}
		if( userInfo.getPid() == null || userInfo.getPid() <= 0 ){
			return -1;
		}
		if( fee.compareTo(new BigDecimal("0")) <=0){
			return -1;
		}
		//fee 0.45
		if( money.compareTo(new BigDecimal("0")) <=0){
			return -1;
		}
		
		//
		BigDecimal commission = money.multiply(fee);
		commission = commission.setScale(2, BigDecimal.ROUND_HALF_UP);
		if (commission.compareTo(new BigDecimal("0.00")) <=0) {
			return -1;
		}
		
		//notice + addMoney 处理
		String ip = "";
		Integer pId = userInfo.getPid();
		User pUserInfo = daoUser.getUser(pId);
		if(pUserInfo == null){
			return -5;
		}
		//20160715 郑总 改推荐的方式：vip推荐了金钻不能返45%得找他的上级看是否是金钻。 vip同级推荐有45%  -jane
		//20160719 郑总 改回原来的推荐方式， 改回原来.  -jane
//		User recommenUserInfo = daoUser.getUser(pId);
//		if( level.equals("gold") && !recommenUserInfo.getLevel().equals(level)){
//			log.info("会员升级为"+level+"推荐人不是gold");
//			pId = recommenUserInfo.getPid();
//			if(pId ==null || pId <=0){
//				log.info("会员升级为"+level+"上级的上级没有-7");
//				return -7;
//			}
//			User topUserInfo = daoUser.getUser(recommenUserInfo.getPid());
//			if(topUserInfo.getLevel().equals(level)){
//				pId = topUserInfo.getId();    //使用了上级在上级
//				log.info("上级的上级ok会员升级"+pId);
//			}else{
//				log.info("会员升级上级的上级也不是"+level+pId);
//				return -5;
//			}
//		}
//		if(level.equals("vip") && recommenUserInfo.getLevel().equals("comm")){
//			return -6;
//		}
		//end
		
		
		Account accInfo = daoAcc.getUserAccount(pId);
		Integer accountId;
		if (accInfo == null) {
			accountId = daoAcc.initUserAcount(pId);
		} else {
			accountId = accInfo.getId();
		}
		daoAccLog.addLog(accountId, sn, ip);
		// 账户变动前记录日志
		
		res = daoAcc.addMoney(accountId, pId, commission);
		AccountNotice notice = new AccountNotice();
		notice.setAccountId(accountId);
		notice.setUserid(pId);
		notice.setMoney(commission);// 现金

		notice.setTradeType((int) type); //交易类型
		String snTemp = PrimaryGenerater.getInstance().next();
		notice.setCsn(sn);// 这笔转账动作流水号
		notice.setSn(snTemp);// 唯一流水号
		notice.setOuterTime(new Date());
		notice.setOperator(-1); // -1系统操作

		notice.setTitle(String.format("由被推荐人%s升级,增加+%s",userInfo.getName(), commission));
		notice.setPaymentId(3);// 系统操作
		notice.setIp(ip);
		notice.setIsPaid((byte) 1);// 已付款
		notice.setMoneyType((short) 1);// 现金类型1,
		notice.setCreateTime(new Date());
		notice.setFromUserId(userId); // 推荐奖来自哪个用户
		// 在查
		Account downAccInfo = daoAcc.selectByPrimaryKey(accountId);
		notice.setMoneyDown(downAccInfo.getMoney()); // 结存现金余额
		notice.setCloudMoneyDown(downAccInfo.getCloudMoney()); // 结存商币余额
		res = daoNotice.insert(notice);
	
		//三级推荐 - 会员升级
		if(pUserInfo.getPid() !=null){
			threeUpgradeCommission(level, pUserInfo.getPid(), userId, money, sn, type);
		}
		
		return res;
	}
	
	/**
	 * 用余额(会员升级)vip[100],gold[1000]
	 * @param level
	 * @param userId
	 * @param money   是升级费用的总额， 例如 vip=100 , gold=1000
	 * @param sn
	 * @return
	 */
	@Override
	public Integer memberUpgradeByCash(String level,Integer userId, BigDecimal money,String sn){
		Integer res = -1;
		//trade_type 交易类型\14余额会员升级推荐人返现金
		Integer type = 14;
		//原先就一级推荐是 45%
		//改成三级推荐后 是 30% ,20% ,10%
//		BigDecimal fee = new BigDecimal("0.45");
//		BigDecimal fee = new BigDecimal("0.3");
//		res = memberUpgrade(level, userId, money, fee, sn, type);
		
		//20160827新规则 无限级50%奖励
		res = everMemberUpgrade(level, userId, money, sn, type);
		return res;
	}

	/**
	 * 在线支付(会员升级)vip[100],gold[1000]
	 * @param level
	 * @param userId
	 * @param money  是升级费用的总额， 例如 vip=100 , gold=1000
	 * @param sn
	 * @return
	 */
	@Override
	public Integer memberUpgradeByOnline(String level,Integer userId, BigDecimal money,String sn){
		Integer res = -1;
		//trade_type 交易类型\15在线支付会员升级推荐人返现金
		Integer type = 15;
		//原先就一级推荐是 45%
		//改成三级推荐后 是 30% ,20% ,10%
//		BigDecimal fee = new BigDecimal("0.45");
//		BigDecimal fee = new BigDecimal("0.3");
//		res = memberUpgrade(level, userId, money, fee, sn ,type);
		
		//20160827新规则 无限级50%奖励
		res = everMemberUpgrade(level, userId, money, sn, type);
		return res;
	}
	
	/**
	 * 管理后台操作充值商币 给推荐人返币
	 * @param total    总金额，消费总额 。后台操作如果是会员的话， 进来的总金额是后台输入的币数
	 * @param type     交易类型 B收款， C消费
	 * @param uInfo		后台操作的用户对象
	 * @param sn
	 * @param actionType	后台操作时选择的值 可是消费，收款 或其他 方便于后期扩展  doNot=不执行规则 
	 * @return
	 */
	@Override
	public Integer adminAddCloudMoney(BigDecimal total,String type, User uInfo, String sn, String actionType) {
		Integer res = -1;
		Integer referrerType = 23; // trade_type 交易类型
									// 23后台加商币给推荐人返币\24后台加商币给合伙人返币
		if(actionType.equals("doNot")){
			//不执行规则
			return -99;
		}
		if(uInfo == null || uInfo.getId() ==null || uInfo.getPid() == null){
			return -2;
		}
		//金钻、基数是消费总额: 增加商币乘100除15跟商家一样
		//普通会员：基数是=增加商币 【 没有乘100除15】跟商家不一样
		//后台操作如果是会员的话， 进来的总金额是后台输入的币数
		if( (uInfo.getIsMerchant() == null || uInfo.getIsMerchant() != 1) && uInfo.getLevel().equals("gold")){
			// 公式：( 收到商币总额 乘 100 除以 15 )  当不是商家且为金钻会员时的基数跟商家一样(规则 20160909)
			BigDecimal totalCloudMoney = total.multiply(new BigDecimal("100"))
					.divide(new BigDecimal("15"), 2, BigDecimal.ROUND_HALF_DOWN);
			total = totalCloudMoney;
		}
		
		// 操作人operator -1 系统
//		res = referrerCloudMoney(total, fee, uInfo.getPid(), uInfo.getId(), sn, referrerType);
		res = adminCommission(total, type, uInfo.getId(), uInfo.getId(), sn, referrerType);

		return res;
	}
	
	/**
	 * 管理后台操作充商币 如果收款方是商家 给合伙人返币
	 */
	@Override
	public Integer adminAddCloudMoneyPartner(BigDecimal total,User toUserInfo, String sn, String actionType) {
		Integer res = -1;
		Integer partnerType = 24; // 23后台加商币给推荐人返币\24后台加商币给合伙人返币
		if(actionType.equals("doNot")){
			//不执行规则
			return -99;
		}
		if (toUserInfo.getIsMerchant() != null && toUserInfo.getIsMerchant() == 1) {
			// 情景: 商家收款
			// 操作: 给合伙人返
			// 根据商家所属于地区
			commissionPartner(toUserInfo.getId(), -1, total, sn, partnerType,"adminAddCloudMoneyPartner");
		}else{
			return -4;
		}
		return res;
		
	}
	
	/**
	 * totalCloudmoney 就是消费总额
	 */
	@Override
	public Integer buyCloudMoney(BigDecimal totalCloudmoney,BigDecimal fee,Integer userid, String sn ,Integer tradeType ){
	    
		//20160810 郑总改规则 使用二级分销 统一入口
		
		/*
		 * 因为之前的fee写在CloudUserGoodsServiceImpl.java 内，现在在不改之前代码，
		 * 根据fee 判断 type是C 消费行为， 还是B收款行为
		 */
		String type = "C";
		if(fee.compareTo(new BigDecimal("0.03")) == 0){
			type = "C";
		}else if( fee.compareTo(new BigDecimal("0.02")) == 0 ){
			//给商家 推荐人返币   比例是2% 商家收款行为
			//总额=( selfCloudMoney 乘以 100 在除以15  ) 进来之前金额已经换算过后的
			type = "B";
		}
		transferCommission(totalCloudmoney, type, userid, userid, sn, tradeType);
		
		if(type.equals("B")){
			// 返给合伙人 购买商币也定义为商家收款  消费行为
			Integer partnerType = 11;	//就是trade_type用于合伙人返币上\10余额转账给推荐人返币\11余额转账给合伙人返币
			commissionPartner(userid, userid, totalCloudmoney, sn, partnerType,"buyCloudMoney");
		}
		
				
		/**
		 * 
		 *之前的规则
		User uInfo = daoUser.getUser(userid);
	    if(uInfo == null){
	    	return -2;
	    }
	    if(uInfo.getPid()==null || uInfo.getPid() == 0 ){
	    	return 1;
	    }
	    User pInfo = daoUser.getUser(uInfo.getPid());
	    if(ApiUtils.objIsEmpty(pInfo)){
	    	return -3;
	    }
	    Integer pId = uInfo.getPid();
	    Integer userId = uInfo.getId();
		referrerCloudMoney(totalCloudmoney, fee, pId, userId,sn,tradeType);
		
		*END
		*/
		
		return 1;
	}
	
	/**
	 * 三级推荐人 从第二级 (转账)
	 * @param total
	 * @param type
	 * @param userId  对应的是交易行为的pId
	 * @param fromUserid  这笔交易行为的发起userid
	 * @param sn
	 * @param referrerType
	 * @return
	 */
//	protected Integer threeTransferCommission(BigDecimal total,String type,Integer userId, Integer fromUserid,String sn, Integer referrerType){
//		log.info("三级推荐TransferCommission:"+type + "["+sn+"]"+"Uid:"+userId +" T:"+total +" From:"+fromUserid);
//		if(!type.equals("C") && !type.equals("B")){
//			return -2;
//		}
//		BigDecimal fee2 = BigDecimal.ZERO;
//		BigDecimal fee3 = BigDecimal.ZERO;
//		if(type.equals("C")){
//			//消费行为
//			fee2 = new BigDecimal("0.02");	//2%二级
//			fee3 = new BigDecimal("0.01");  //1% 三级
//		}else if(type.equals("B")){
//			//商家行为
//			fee2 = new BigDecimal("0.01");
//			fee3 = new BigDecimal("0.01");
//		}
//		//查 userId的是否有pId
//		User userInfo = daoUser.getUser(userId);
//
//		// 检查 是否有推荐人
//		if (userInfo !=null && userInfo.getPid() != null ) {
//			Account accInfo = daoAcc.getUserAccount(userId);
//			if (accInfo == null) {
//				daoAcc.initUserAcount(userId);
//			}
//			//第二级
//			// 操作人operator -1 系统
//			log.info("三级推荐TransferCommission:第二级:"+"["+sn+"]"+fee2+" , "+userInfo.getPid() +" T:"+total);
//			referrerCloudMoney(total, fee2, userInfo.getPid(), fromUserid, sn, referrerType);
//			
//			//debug用途， 以后可注释或删除
//			BigDecimal checkCloudMoney = total.multiply(fee2).setScale(2, BigDecimal.ROUND_DOWN);
//			if (checkCloudMoney.compareTo(new BigDecimal("0.00")) <=0){
//				log.info("三级推荐TransferCommission:第二级:金额为0 时无操作"+"["+sn+"]"+fee2+" , "+userInfo.getPid() +" TC:"+checkCloudMoney);
//			}
//			
//			//检查三级推荐人
//			User user2Info = daoUser.getUser(userInfo.getPid());
//			if (user2Info !=null && user2Info.getPid() != null && user2Info.getPid() != 0) {
//				Account acc2Info = daoAcc.getUserAccount(user2Info.getPid());
//				if (acc2Info == null) {
//					daoAcc.initUserAcount(user2Info.getPid());
//				}
//				log.info("三级推荐TransferCommission:第三级:"+"["+sn+"]"+fee3+" , "+user2Info.getPid() +" T:"+total );
//				referrerCloudMoney(total, fee3, user2Info.getPid(), fromUserid, sn, referrerType);
//				
//				//debug用途， 以后可注释或删除
//				checkCloudMoney = total.multiply(fee3).setScale(2, BigDecimal.ROUND_DOWN);
//				if (checkCloudMoney.compareTo(new BigDecimal("0.00")) <=0){
//					log.info("三级推荐TransferCommission:第三级:金额为0 时无操作"+"["+sn+"]"+fee3+" , "+user2Info.getPid() +" TC:"+checkCloudMoney);
//				}
//			}
//		}
//		
//		return -1;
//	}
	
	/**
	 * 会员升级  三级推荐 (二级和三级部分)
	 * 20160810郑总改规则 改成二级分销
	 * @param level
	 * @param pId	      升级行为用户的 上级id
	 * @param userId  升级行为的用户id
	 * @param money   总金额
	 * @param sn
	 * @param type
	 * @return
	 */
	protected Integer threeUpgradeCommission(String level,Integer pId, Integer userId,BigDecimal money, String sn,Integer type){
		Integer res = -1;
		BigDecimal fee2 = new BigDecimal("0.2");  //第二级 20%
		BigDecimal fee3 = new BigDecimal("0.1");  //第三级 10%
		//trade_type \14余额会员升级推荐人返现金\15在线支付会员升级推荐人返现金
		//第二级
		res = upgradeCommission(level, pId, userId, money, fee2, sn, type);
		//第三级
		//20160810郑总改规则 改成二级分销
//		User userInfo = daoUser.getUser(pId);
//		if(res > 0 && userInfo.getPid() !=null ){
//			res = upgradeCommission(level, userInfo.getPid(), userId, money, fee3, sn, type);
//		}
		return res;
	}
	
	/**
	 * 
	 * @param level
	 * @param pId		  !主要根据这个id
	 * @param userId
	 * @param money
	 * @param fee
	 * @param sn
	 * @param type
	 * @return
	 */
	protected Integer upgradeCommission(String level,Integer pId, Integer userId,BigDecimal money,BigDecimal fee, String sn,Integer type){
 
		Integer res = -1;
		if (pId == null || userId == null || money.compareTo(BigDecimal.ZERO)<=0) {
			return -1;
		}
		String ip = "";
		// 推荐奖  现金(money*fee)
		BigDecimal intoMoney = money.multiply(fee);
		intoMoney = intoMoney.setScale(2, BigDecimal.ROUND_DOWN);
		if (intoMoney.compareTo(new BigDecimal("0.00")) <=0 ) {
			return -6;
		}

		User userInfo = daoUser.getUser(pId);
		User fromUserInfo = daoUser.getUser(userId);
		if(userInfo == null){
			return -3;
		}
		Account accInfo = daoAcc.getUserAccount(pId);
		Integer accountId;
		if (accInfo == null) {
			accountId = daoAcc.initUserAcount(pId);
		} else {
			accountId = accInfo.getId();
		}
		daoAccLog.addLog(accountId, sn, ip);
		// 账户变动前记录日志

		res = daoAcc.addMoney(accountId, pId, intoMoney);
		AccountNotice notice = new AccountNotice();
		notice.setAccountId(accountId);
		notice.setUserid(pId);
		notice.setMoney(intoMoney);// 现金

		notice.setTradeType((int) type); //交易类型
		String snTemp = PrimaryGenerater.getInstance().next();
		notice.setCsn(sn);// 这笔转账动作流水号
		notice.setSn(snTemp);// 唯一流水号
		notice.setOuterTime(new Date());
		notice.setOperator(-1); // -1系统操作

		notice.setTitle(String.format("由被推荐人%s升级,增加+%s",fromUserInfo.getName(), intoMoney));
		notice.setPaymentId(3);// 系统操作
		notice.setIp(ip);
		notice.setIsPaid((byte) 1);// 已付款
		notice.setMoneyType((short) 1);// 现金类型1,
		notice.setCreateTime(new Date());
		notice.setFromUserId(userId); // 推荐奖来自哪个用户
		// 在查
		Account downAccInfo = daoAcc.selectByPrimaryKey(accountId);
		notice.setMoneyDown(downAccInfo.getMoney()); // 结存现金余额
		notice.setCloudMoneyDown(downAccInfo.getCloudMoney()); // 结存商币余额
		res = daoNotice.insert(notice);
 
		return res;
	}
	
	/**
	 * 把会员等级字符转成数字 以方便判断等级之间层级
	 * @param level
	 * @return
	 */
	protected Integer levelToNum(String level){
		Integer num;
		switch (level) {
		case "comm":
			num = 0;
			break;
		case "vip":
			num = 1;
			break;
		case "gold":
			num = 2;
			break;
		default:
			num = 0;
			break;
		}
		return num;
	}
	/**
	 * 判断两个用户的等级是否同级或以有
	 * 如果后者比前者的等级高或相同 返回1
	 * @param level
	 * @param comLevel
	 * @return
	 */
	protected Integer compUserLever(String level, String comLevel){
		Integer res = -1;
		Integer levelNum = levelToNum(level);
		Integer comLevelNum = levelToNum(comLevel);
//		log.info("主来源:"+levelNum+" -->-- "+comLevelNum);
		if(comLevelNum >= levelNum){
			return new Integer("1");
		}
		return res;
	}
	/**
	 * 查用户所有上线 遍历所有
	 * 20160808 郑总要改新的游戏规则 改二级分销并要一直向上推直到找到同级或以上  -jane
	 * 
	 * @param levelNum   等级数，即查找到几级为止。 2就是总要找到二级为止要不然一直往上找
	 */
	@Override
	public List<Integer> getAllPuser(Integer userid ,Integer levelNum){
//		   log.info("getAllPuser==>主查询:"+userid);
		   List<Integer> list = new ArrayList<Integer>();
		   User userInfo = daoUser.getUser(userid);
		   if(userInfo == null || userInfo.getPid() ==null){
			   return list;
		   }
		   User pUserInfo = daoUser.getUser(userInfo.getPid());
		   if(pUserInfo == null){
			   return list;
		   }
		   //推荐人是被推荐人的等级相同或以上才有推荐奖励， 否则在往上找
		   if(compUserLever(userInfo.getLevel(), pUserInfo.getLevel()) > 0){
			   list.add(pUserInfo.getId());
		   }
		   
		   //向无限上级
		   List<Integer> c = getAllSub(pUserInfo.getId() ,userInfo.getLevel(), list , new Integer("1") ,levelNum, userid);
		   if(c.size() > 0 ){
			   //list.addAll(c);
			   return c;
		   }
	
		return list;
	}
	/**
	 * 无限往上查找同等或以上级别的推荐人
	 * @param userid
	 * @param userLevel  最开始的user等级
	 * @param list
	 * @param i
	 * @param levelNum   等级数，即查找到几级为止。 2就是总要找到二级为止要不然一直往上找
	 * @return
	 */
	protected List<Integer> getAllSub(Integer userid ,String userLevel, List<Integer> list , Integer i ,Integer levelNum, Integer fromUserId){
		   
		   User userInfo = daoUser.getUser(userid);
		   if(userInfo == null || userInfo.getPid() == null){
			   return list;
		   }
		   User pUserInfo = daoUser.getUser(userInfo.getPid());
		   if(pUserInfo == null){
			   return list;
		   }
		   //防脏数据
		   if(pUserInfo.getId().equals(fromUserId)){
			   return list;
		   }
		   //推荐人是被推荐人的等级相同或以上才有推荐奖励， 否则在往上找
		   if(compUserLever( userLevel , pUserInfo.getLevel()) > 0){
			   list.add(pUserInfo.getId());
		   }
		   //程序为防死循环 暂设定为在100数下 
		   if(i <= 100)
		   {
			   if(list.size() < levelNum ){
				   List<Integer> c = getAllSub(pUserInfo.getId() ,userLevel, list , i++ ,levelNum, fromUserId);
				   //list.addAll(c);
			   }
		   }
		   
		return list;
	}

	/**
	 * 实际执行推荐奖励 设置 比例值和操作
	 * 二级分销(转账) 20160810 改游戏规则
	 * 包含 一级和二级
	 * 加规则 ，实行现金奖励  20160818
	 * 
	 * @param total			总金额！
	 * @param type
	 * @param fromUserid
	 * @param sn
	 * @param referrerType
	 * @return
	 */
	protected Integer doTransferCommission(BigDecimal total,String type, Integer fromUserid,String sn, Integer referrerType){
		log.info("两级推荐twoTransferCommission:"+type + "["+sn+"]"+"Fid:"+fromUserid +" T:"+total  );
		log.info("新游戏规则 奖励现金20160818");
		if(!type.equals("C") && !type.equals("B")){
			return -2;
		}
		Map<Integer, BigDecimal> feeMap = new HashMap<Integer, BigDecimal>();
		Map<Integer, BigDecimal> cashFeeMap = new HashMap<Integer, BigDecimal>();
		if(type.equals("C")){
			//消费行为
			feeMap.put(new Integer("1"), new BigDecimal("0.03")	); //3%一级  奖励商币的比例
			feeMap.put(new Integer("2"), new BigDecimal("0.02")	); //2%二级  奖励商币的比例
			//现金奖励
			cashFeeMap.put(new Integer("1"), new BigDecimal("0.03")	); //第一级3%   现金奖励比例，基数为平台收的15%
			cashFeeMap.put(new Integer("2"), new BigDecimal("0.02")	); //第二级2%   现金奖励比例，基数为平台收的15%
			
		}else if(type.equals("B")){
			//商家行为
			feeMap.put(new Integer("1"), new BigDecimal("0.02")	); //2%一级
			feeMap.put(new Integer("2"), new BigDecimal("0.01")	); //1%二级
			//现金奖励
			cashFeeMap.put(new Integer("1"), new BigDecimal("0.02")	); //第一级2%   现金奖励比例，基数为平台收的15%
			cashFeeMap.put(new Integer("2"), new BigDecimal("0.01")	); //第二级1%   现金奖励比例，基数为平台收的15%
		}
		
		//往上查找所有推荐人,得到的结果集内的id 都是需要操作推荐加币的用户 . 第二参数为要查几级
		//查二级
		List<Integer> list = getAllPuser(fromUserid, new Integer("2"));
		
		//遍历所有应该加币的推荐人 ，并取得对应的推荐比例取 doFee
		for(int i=0; i<list.size(); i++){
			Integer userId = list.get(i);
			Integer n = i+1;
			BigDecimal doFee = BigDecimal.ZERO;
			doFee = feeMap.get(n);

			//现金奖励
			BigDecimal doCashFee = BigDecimal.ZERO;
			doCashFee = cashFeeMap.get(n);
			
			//log debug用途， 以后可注释或删除
			BigDecimal checkCloudMoney = total.multiply(doFee).setScale(2, BigDecimal.ROUND_DOWN);
			if (checkCloudMoney.compareTo(new BigDecimal("0.00")) <=0){
				log.info(n+"级推荐twoTransferCommission:金额为0 时无操作"+"["+sn+"]"+doFee+" , "+userId +" TC:"+checkCloudMoney);
			}else{
				log.info(n+"级推荐twoTransferCommission:"+"["+sn+"]"+doFee+" , "+userId +" T:"+total);
				referrerCloudMoney(total, doFee, userId, fromUserid, sn, referrerType);
				
				//新游戏规则 奖励现金20160818
				//【这个金额得是平台收的15%】 bshCashMoney
				BigDecimal bshCashMoney = total.multiply(new BigDecimal("0.15"));

				//20160826 郑总改规则，去掉返现金规则
				//20160826b 先不去掉等做好全部在一起上
				//20160827做好新规则一起上， 无限级50%,同时去掉返现金
//				referrerMoney(bshCashMoney, doCashFee, userId, fromUserid, sn, referrerType);
			}

		}
				
		return -1;
	}
	
	/**
	 * 转账相关的推荐奖励入口 ，不管是二级分销还是三级都在这个方法内完成
	 * @param total   			总金额
	 * @param type    			类型是消费行为C , 还是收款行为 B
	 * @param userId		!重要 主要根据这个id进行相关操作，可能是付款者,也可是收款者id 
	 * @param fromUserid 	            这笔交易的发起者id只用于记录作用
	 * @param sn      			当前这笔交易流水号      
	 * @param referrerType		交易类型id ,对应数据库内的trade_type
	 * @return
	 */
	protected Integer transferCommission(BigDecimal total,String type,Integer userId, Integer fromUserid,String sn, Integer referrerType){
		Integer res = -1;
		if(!type.equals("C") && !type.equals("B")){
			return -2;
		}
		User userInfo = daoUser.getUser(userId);
		if(userInfo == null){
			return -3;
		}
		
		/*
		 * 三级分销- 在20160810之前的老规则
		 * 

		if(type.equals("C")){
			//消费行为
			BigDecimal fee = new BigDecimal("0.03");
		}else if(type.equals("B")){
			//商家行为
			BigDecimal fee = new BigDecimal("0.02"); // 2.会员收款行为 他对应的推荐人得到
		}
		// 操作人operator -1 系统
		//fee比例不同 ，对应是消费还是收款行为
		res = referrerCloudMoney(total, fee, userInfo.getPid(), fromUserid, sn, referrerType);
		//三级推荐人
		threeTransferCommission(total,type,userInfo.getPid(),fromUserid,sn,referrerType);
		
		*
		* END 三级老规则
		*/

		//郑总新规则  二级分销 20160810
		//搜索所有的符合条件的上级，无限向上找 . 该方法会从第一级开始， 只要放入原始的交易发起者id
		//20160827新规则 无限级50%奖励
//        doTransferCommission(total,type,userId,sn,referrerType);
		//*END 二级分销 20160810
		
		//20160827新规则 无限级50%奖励
		everTransfer(total,type,userId,sn,referrerType);
		
		return res;
	}
	
	/**
	 * 消费行为 ，商家收款 合伙奖励相关操作
	 * 奖励商币
	 * 奖励现金新规则 20180818
	 * 
	 * @param toUserId		！主要，根据该id 查商家信息, 例如商家收款的收款方
	 * @param fromUserId	 暂不用 保留
	 * @param total			总金额!!实际消费行为的收款总额!!
	 * @param sn			流水号
	 * @param partnerType	交易类型数字
	 * @param type 			场景,使用到该方法的场景
	 * @return
	 */
	protected Integer commissionPartner(Integer toUserId,Integer fromUserId,BigDecimal total,String sn,Integer partnerType,String type){
		Integer res = -1;
		User toUserInfo = daoUser.getUser(toUserId);
		// 返给合伙人 (当被转账人为商家时)-商家收款
		// !!! 一个用户对应多个商户，不同商户会属于不同区域 !!!!
		if (toUserInfo.getIsMerchant() != null && toUserInfo.getIsMerchant() == 1) {
			// 情景: 商家收款
			// 操作: 给合伙人返
			// 根据商家所属于地区

			List<Map<String, Object>> list = daoMer.getValidMerchantByUserId(toUserId);
			// ========
			// 目前先以用户只有一个商户先走通
			// =========
			if (list.size() == 1) {
				Integer merchantId = (Integer) list.get(0).get("id");
				res = recommendPartner(merchantId, fromUserId, toUserId, total, sn, partnerType,type);
			}

		}
		return res;
				
	}
	
	/**
	 * 新规则 收取上级收入的50% 无限
	 * 会员升级费用 - 奖励得现金
	 * 
	 * @return
	 */
	protected Integer everMemberUpgrade(String level, Integer userId, BigDecimal money, String sn, Integer type) {
		log.info("everMemberUpgrade:start:"+money+" sn:["+sn+"]" +type+level);
		Integer res = -1;
		if(level == null || money == null || sn == null){
			return -2;
		}
		
		if(this.everMemberFee.compareTo(BigDecimal.ZERO) <=0){
			return -3;
		}
		if(this.everMemberUpgradeFee.compareTo(BigDecimal.ZERO) <=0){
			return -4;
		}
		//得到要返的用户list
		//查100级
		List<Integer> listUsers = getAllPuser(userId, new Integer("100"));
		if(listUsers.size() <=0){
			log.info("ever50%MemberUpgrade:: 没有找到符合条件的推荐人,"+userId+" sn:["+sn+"]" +type+level);
			return -5;
		}
		
		//得到基数
		BigDecimal doMoney = money.multiply(this.everMemberUpgradeFee).setScale(2, BigDecimal.ROUND_DOWN);
		if(doMoney.compareTo(BigDecimal.ZERO)<=0){
			return -6;
		}
		//计算比例和推荐总额放在for内计算 
		BigDecimal doEveyForFee = new BigDecimal("1");
		//遍历所有应该奖励的推荐人 ，注意基数
		for(int i=0; i<listUsers.size(); i++){
			Integer doUserId = listUsers.get(i);
			if(doMoney.compareTo(BigDecimal.ZERO) <=0 ){
				break;
			}
			res = upgradeCommission(level, doUserId, userId, doMoney, doEveyForFee, sn, type);
			doMoney = everSum(doMoney, this.everMemberFee );

			log.info(i+"级推荐everMemberUpgrade:"+"["+sn+"]"+doUserId+" , "+userId +" Money:"+doMoney);
		}
		
		return res;
	}
	
	protected static BigDecimal everSum(BigDecimal money, BigDecimal fee) {
		BigDecimal total = money.multiply(fee).setScale(2, BigDecimal.ROUND_DOWN);
		return total;
	}
	
	/**
	 * 
	 * @param total
	 * @param type
	 * @param fromUserid
	 * @param sn
	 * @param referrerType
	 * @return
	 */
	protected Integer everTransfer(BigDecimal total,String type, Integer fromUserid,String sn, Integer referrerType){
		log.info("everTransfer:"+type + "["+sn+"]"+"Fid:"+fromUserid +" T:"+total  );
		Integer res = -1;
		
		if(!type.equals("C") && !type.equals("B")){
			return -2;
		}
		if(this.everTransferSaleFee.compareTo(BigDecimal.ZERO) <=0){
			return -3;
		}
		if(this.everTransferMerchantFee.compareTo(BigDecimal.ZERO) <=0){
			return -4;
		}
		BigDecimal doMoney = BigDecimal.ZERO;
		if(type.equals("C")){
			//消费行为
			//得到基数
			doMoney = total.multiply(this.everTransferSaleFee).setScale(2, BigDecimal.ROUND_DOWN);
			if(doMoney.compareTo(BigDecimal.ZERO)<=0){
				return -6;
			}
		}else if(type.equals("B")){
			//商家行为
			//得到基数
			doMoney = total.multiply(this.everTransferMerchantFee).setScale(2, BigDecimal.ROUND_DOWN);
			if(doMoney.compareTo(BigDecimal.ZERO)<=0){
				return -6;
			}
		}
		//计算比例和推荐总额放在for内计算 
		BigDecimal doEveyForFee = new BigDecimal("1");
		
		//往上查找所有推荐人,得到的结果集内的id 都是需要操作推荐加币的用户 . 第二参数为要查几级
		//查100级
		List<Integer> listUsers = getAllPuser(fromUserid, new Integer("100"));
		
		//遍历所有应该加币的推荐人 ，注意基数
		for(int i=0; i<listUsers.size(); i++){
			Integer doUserId = listUsers.get(i);
			if(doMoney.compareTo(BigDecimal.ZERO) <=0 ){
				break;
			}
			referrerCloudMoney(doMoney, doEveyForFee, doUserId, fromUserid, sn, referrerType);
			doMoney = everSum(doMoney, this.everTransferFee );

			log.info(i+"级推荐everTransfer:"+"["+sn+"]"+doUserId+" , "+fromUserid +" Money:"+doMoney);
		}
		return res;
	}
	
	/**
	 * 后台操作相关的推荐奖励统一入口 ，不管是二级分销还是三级都在这个方法内完成
	 * @param total   			总金额
	 * @param type    			类型是消费行为C , 还是收款行为 B
	 * @param userId		!重要 主要根据这个id进行相关操作，可能是付款者,也可是收款者id 
	 * @param fromUserid 	            这笔交易的发起者id只用于记录作用
	 * @param sn      			当前这笔交易流水号      
	 * @param referrerType		交易类型id ,对应数据库内的trade_type
	 * @return
	 */
	protected Integer adminCommission(BigDecimal total,String type,Integer userId, Integer fromUserid,String sn, Integer referrerType){
		Integer res = -1;
		if(!type.equals("C") && !type.equals("B")){
			return -2;
		}
		//无限级50%奖励
		everTransfer(total,type,userId,sn,referrerType);
		
		return res;
	}
	
	
}
